package com.example.screenprojection.Socket;

import android.graphics.Bitmap;

import com.example.screenprojection.Utils.MyUtils;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class BitmapServerRunnable implements Runnable {

    private static final String TAG = "BitmapServerRunnable";

    private ServerSocket serverSocket;
    private Socket socket;
    private int port;
    private Bitmap bitmap;
    private int width;
    private int height;


    public void setPort(int port) {
        this.port = port;
    }

    public void setBitmap(Bitmap bitmap, int width, int height) {
        this.bitmap = bitmap;
        this.width = width;
        this.height = height;
    }

    @Override
    public void run() {
        ServerRun();
    }

    public void close() {
        ServerClose();
    }

    private boolean ServerCreate() {
        try {
            serverSocket = new ServerSocket(port, 1);
        } catch (Exception e) {
            e.printStackTrace();
            if (listener != null) {
                listener.onServerClose();
            }
            return false;
        }
        return true;
    }

    private boolean ServerListen() {
        try {
            socket = serverSocket.accept();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        if (listener != null) {
            listener.onServerConnect();
        }
        return true;
    }

    private boolean ServerIsConnect() {
        return socket != null && !socket.isClosed() && socket.isConnected();
    }

    private void ServerClose() {
        try {
            if (socket != null) {
                socket.close();
                serverSocket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (listener != null) {
            listener.onServerClose();
        }
    }

    private void ServerSleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private final static byte[] PACKAGE_HEAD = {(byte)0xFF, (byte)0xCF, (byte)0xFA, (byte)0xBF, (byte)0xF6, (byte)0xAF, (byte)0xFE, (byte)0xFF};

    private void ServerTransmitBitmap() {
        try {
            DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
            if (bitmap != null) {
                byte[] bytes = MyUtils.BitmaptoBytes(bitmap);
                dataOutputStream.write(PACKAGE_HEAD);
                dataOutputStream.writeInt(width);
                dataOutputStream.writeInt(height);
                dataOutputStream.writeInt(bytes.length);
                dataOutputStream.write(bytes);
            }
            dataOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void ServerRun() {
        if (!ServerCreate()) {
            return;
        }
        while (true) {
            if (!ServerListen()) {
                break;
            }
            while (ServerIsConnect()) {
                ServerTransmitBitmap();
                ServerSleep(10);
            }
        }
    }

    private ServerListener listener;

    public void setListener(ServerListener listener) {
        this.listener = listener;
    }

    public interface ServerListener {
        void onServerConnect();
        void onServerClose();
    }
}
